/**
 * 请求封装
 */
import Vue from 'vue'
import {
	storage
} from './storage'
import appConfig from "./app.config";
import queryString from 'query-string'
//是否显示Loading,配置是否刷新令牌,刷新token地址,登录地址,服务器地址,携带请求信息,超时时间
let {showLoading,needRefresh,refreshUrl,loginUrl,webServiceUrl,withCredentials,timeout} = appConfig.requestConfig;
//访问令牌名称,刷新token名称
let{accessTokenName,refreshTokenName} = appConfig.storageConfig;
//提示,清除,返回上一级,无效的访问
let {showMessage,storageClear,backToPrevious,invalidAccessToken} = appConfig.returnHandleConfig;
let subscribers = [] //请求队列
let isRefreshing = true; //刷新中
//拦截器
uni.addInterceptor('request', {
	//请求拦截
	invoke(args) {
		// request 触发前拼接 url 
		args.url = webServiceUrl + args.url
	},
	//响应拦截器
	complete(res) {
		returnHandle(res.data)
	}
})

/**
 * 拦截处理
 * @param response
 */
function returnHandle(response) {
	//显示提示
	if (showMessage.indexOf(response.errCode) != -1) {
		uni.showToast({
			title: response.errMsg,
			icon: "none",
			duration: 2000
		});
	}
	//清理缓存
	if (storageClear.indexOf(response.errCode) != -1) {
		storage.clear()
	}
	//返回上一级
	if (backToPrevious.indexOf(response.errCode) != -1) {
		uni.navigateBack({
			delta: 1
		});
	}
	//凭证失效
	if (invalidAccessToken.indexOf(response.errCode) != -1) {
		//登陆
		loginFn()
	}
}

/**
 * 网络请求,类型GET
 * @param {String} url
 * @param {Object} params
 * @return {Object}
 */
export function get(url, params = {}) {
	let loadingInstance = null;
	if (showLoading) {
		uni.showLoading({
			title: '加载中'
		});
	}
	return new Promise((resolve, reject) => {
		const timestamp = (new Date()).getTime() / 1000
		const expire = storage.getExpire(accessTokenName)
		if (timestamp > expire - 1800 && url !== loginUrl && expire >= 0 && needRefresh ||
			expire == -1 && url !== loginUrl) {
			resolve(reload(url, params,{}, 'get'))
			if (showLoading) {
				uni.hideLoading();
			}
			return
		}
		uni.request({
			url: url,
			data: params,
			method: "GET",
			timeout: timeout,
			withCredentials: withCredentials,
			header: {
				[accessTokenName]: storage.get(accessTokenName)
			},
			success: (res) => {
				if (showLoading) {
					uni.hideLoading();
				}
				resolve(res.data)
			},
			fail: (res) => {
				if (showLoading) {
					uni.hideLoading();
				}
				resolve(res)
			}
		});
	})
}

/**
 * 网络请求,类型POST
 * @param {String} url
 * @param {Object} params
 * @return {Object}
 */
export function post(url,query = {}, params = {}) {
	let loadingInstance = null;
	if (showLoading) {
		uni.showLoading({
			title: '加载中'
		});
	}
	return new Promise((resolve, reject) => {
		const timestamp = (new Date()).getTime() / 1000
		const expire = storage.getExpire(accessTokenName)
		if (timestamp > expire - 1800 && url !== loginUrl && expire >= 0 && needRefresh ||
			expire == -1 && url !== loginUrl) {
			resolve(reload(url, query , params, 'post'))
			if (showLoading) {
				uni.hideLoading();
			}
			return
		}
		if(JSON.stringify(query) !== "{}"){
			url = `${url}?${queryString.stringify(query)}`
		}	
		uni.request({
			url: url,
			data: params,
			method: "POST",
			timeout: timeout,
			withCredentials: withCredentials,
			header: {
				[accessTokenName]: storage.get(accessTokenName)
			},
			success: (res) => {
				if (showLoading) {
					uni.hideLoading();
				}
				resolve(res.data)
			},
			fail: (res) => {
				if (showLoading) {
					uni.hideLoading();
				}
				resolve(res)
			}
		});
	})
}

/**
 * 令牌快过期,请求刷新token
 */
function reload(url, query, params={}, method="GET") {
	if (isRefreshing) {
		//登陆
		uni.login({
			provider: 'weixin', //使用微信登录
			success: (result) => {
				post(loginUrl,{}, {
					'code': result.code
				}).then((res) => {
					//存储接口凭证
					storage.set(accessTokenName, res.data[accessTokenName], res.data
						.expire)
					storage.set(refreshTokenName, res.data[refreshTokenName])
					// 获取其它信息
					storage.set("openid", res.data?.openid)
					storage.set("name", res.data?.name)
					subscribers.forEach((callback) => {
						callback()
					})
					subscribers = []
					isRefreshing = true
				})
			}
		});
	}
	isRefreshing = false
	return new Promise((resolve) => {
		subscribers.push(() => {
			if (method === 'get') {
				get(url, query).then((data) => {
					resolve(data)
				})
			} else if (method === 'post') {
				post(url, query, params).then((data) => {
					resolve(data)
				})
			}
		})
	})
}

/**
 * 登录
 */
export function loginFn() {
	//登陆
	uni.login({
		provider: 'weixin', //使用微信登录
		success: (result) => {
			post(loginUrl,{}, {
				'code': result.code
			}).then((res) => {
				//存储接口凭证
				storage.set(accessTokenName, res.data[accessTokenName], res.data
					.expire)
				storage.set(refreshTokenName, res.data[refreshTokenName])
				// 获取其它信息
				storage.set("openid", res.data?.openid)
				storage.set("name", res.data?.name)
			})
		}
	});

}